﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.ViewModels;
using Sasa.QualityTools.CodeAnalysis.Core.VisualStudio;
using Sasa.QualityTools.CodeAnalysis.Core.Models;
using Sasa.QualityTools.CodeAnalysis.Core.Utilities;

namespace Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.Commands.Behaviors.CodeAnalysis.Metrics
{
    public abstract class CreateCodeMetricsCalculatorBehaviorBase : ICommandBehavior<CodeAnalysisCommandExecutionContext>
    {
        protected IUnityContainer Container { get; private set; }


        protected CreateCodeMetricsCalculatorBehaviorBase(IUnityContainer container)
        {
            Container = container;
        }


        public abstract void Behave(CodeAnalysisCommandExecutionContext context);

        protected CodeMetricsCalculatorViewModel BuildupCodeMetricsCalculator(IProject project)
        {
            var model = new CodeMetricsCalculatorViewModel();
            model.Target = project.Name;

            if (!project.IsSupportedCodeAnalysis)
            {
                var reason = (!String.IsNullOrWhiteSpace(project.NotSupportedReason)) ? project.NotSupportedReason : "FxCop Integrator doesn't support to analyze this project.";
                model.SkipPeforming(reason);
                return model;
            }

            var config = CodeAnalysisConfiguration.Load(project.ConfigurationPath);
            config.Override(CodeAnalysisConfiguration.Load(project.Solution.ConfigurationPath));
            if (!config.EnableCodeAnalysis)
            {
                model.SkipPeforming("Code analysis is disabled.");
                return model;
            }

            // The report loader finds the path of tje FxCop report with the command line option.
            // So this behavior have to set model.CommandOption whether on-demand code analysis is skipped or not.
            var option = Container.Resolve<IFxCopIntegratorPackage>().GeneralOption;
            model.CommandPath = option.MetricsPath;
            model.CommandOption = MetricsOptionBuilder.Build(project, option.MetricsVersion);
            foreach (var path in project.ReferenceAssemblyPaths)
            {
                model.ReferenceAssemblyPaths.Add(path);
            }
            model.Filter = new CodeAnalysisResultValueFileNameFilter(config.FilterPatterns);

            var msbuild = MSBuildProject.Load(project.ProjectPath);
            if (msbuild.EnableCodeMetricsCalculationOnBuild)
            {
                model.MarkAsCompletedOnBuildTime();
                return model;
            }

            return model;
        }
    }
}
